﻿using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
using xuni;

namespace xab
{


    public static class LuaBuildUtils
    {


        public static void CopyLuaFilesToTempDir(BuildRules buildRules, bool luaByteMode, StringBuilder sb)
        {
            var sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            //lua文件copy到临时文件夹
            var luaTempDir = "Assets/_LuaTemp/";
            if (!Directory.Exists(luaTempDir))
            {
                Directory.CreateDirectory(luaTempDir);
            }

            //luaRules下匹配的所有文件copy到: Assets/_LuaTemp/
            var luaRules = buildRules.luaRules;
            for (int i = 0, max = luaRules.Count; i < max; ++i)
            {
                var luaRule = luaRules[i];
                for (int j = 0; j < luaRule.paths.Count; ++j)
                {
                    var luaDir = luaRule.paths[j];
                    CopyLuaFilesToDir(luaByteMode, luaDir, luaTempDir, buildRules.displayProgressDialog, sb);
                }
            }

            sw.Stop();
            UnityEngine.Debug.Log($"CopyLuaFilesToTempDir: 总共用时{sw.Elapsed.TotalSeconds}秒");

            AssetDatabase.Refresh();
        }

        static void CopyLuaFilesToDir(bool luaByteMode, string srcLuaDir, string tempLuaDir, bool displayLuaCopyProgress, StringBuilder sb)
        {
            if (luaByteMode)
            {
                var destFiles = Directory.GetFiles(tempLuaDir, "*.lua", SearchOption.AllDirectories);
                var destFilesSet = new HashSet<string>();
                for (var i = 0; i < destFiles.Length; ++i)
                {
                    destFilesSet.Add(destFiles[i].Replace('\\', '/'));
                }

                var srcFiles = Directory.GetFiles(srcLuaDir, "*.lua", SearchOption.AllDirectories);
                if (null != srcFiles && srcFiles.Length > 0)
                {
                    if (!Directory.Exists(tempLuaDir))
                        Directory.CreateDirectory(tempLuaDir);

                    var len = srcLuaDir.Length;
                    var endChar = srcLuaDir[len - 1];
                    if ('/' != endChar && '\\' != endChar)
                        ++len;

                    for (int i = 0; i < srcFiles.Length; i++)
                    {
                        var srcPath = srcFiles[i].Replace('\\', '/');
                        var relaptivePath = srcPath.Remove(0, len);

                        sb.Append(tempLuaDir).Append(relaptivePath).Append(".bytes");
                        var destPath = sb.ToString();
                        sb.Clear();
                        destFilesSet.Remove(destPath);

                        LuaBuildUtils.EncodeLuaFile(srcPath, destPath);
                    }
                }

                //src中没有的(已删除)
                foreach (var item in destFilesSet)
                {
                    UnityEngine.Debug.Log($"CopyLuaFilesToDir: src not exist(delete): {item}");
                    File.Delete(item);
                }
            }
            else
            {
                //都会加上.bytes后缀
                LuaBuildUtils.CopyLuaBytesFiles(srcLuaDir, tempLuaDir, displayLuaCopyProgress, true, true, "*.lua", SearchOption.AllDirectories);
            }

            LuaBuildUtils.CopyLuaBytesFiles(srcLuaDir, tempLuaDir, displayLuaCopyProgress, true, true, "*.pb", SearchOption.AllDirectories); //proto协议文件
        }



        /// <summary>
        /// copy lua文件夹
        /// </summary>
        /// <param name="srcDir"></param>
        /// <param name="destDir"></param>
        /// <param name="showCopyProgress">显示copy进度框</param>
        /// <param name="checkLuaFileModify">lua文件发生了修改才copy</param>
        /// <param name="appendExt">copy lua文件时, 是否添加.bytes后缀</param>
        static void CopyLuaBytesFiles(string srcDir, string destDir, bool showCopyProgress, bool checkLuaFileModify, bool appendExt, string searchPattern, SearchOption searchOption)
        {
            if (!Directory.Exists(srcDir))
                return;

            var destFiles = Directory.GetFiles(destDir, searchPattern, searchOption);
            var destFilesSet = new HashSet<string>();
            for (var i = 0; i < destFiles.Length; ++i)
            {
                destFilesSet.Add(destFiles[i].Replace('\\', '/'));
            }

            var srcFiles = Directory.GetFiles(srcDir, searchPattern, searchOption);
            if (null != srcFiles && srcFiles.Length > 0)
            {
                var tempSb = new StringBuilder();

                if (!Directory.Exists(destDir))
                    Directory.CreateDirectory(destDir);

                destDir = PathUtils.DirEndWithSeparator(destDir);

                var len = srcDir.Length;
                var endChar = srcDir[len - 1];
                if ('/' != endChar && '\\' != endChar)
                    ++len;

                for (int i = 0, max = srcFiles.Length; i < max; i++)
                {
                    var srcPath = srcFiles[i].Replace('\\', '/');
                    var relativePath = srcPath.Remove(0, len);

                    if (showCopyProgress)
                    {
                        var title = string.Format("拷贝lua文件{0}/{1}", i, max);
                        if (EditorUtility.DisplayCancelableProgressBar(title, relativePath, i / (float)max))
                            break;
                    }

                    tempSb.Append(destDir).Append(relativePath);
                    if (appendExt)
                    {
                        tempSb.Append(".bytes");
                    }
                    var destPath = tempSb.ToString();
                    tempSb.Clear();
                    destFilesSet.Remove(destPath);

                    if (!checkLuaFileModify)
                    {
                        File.Copy(srcPath, destPath, true);
                        continue;
                    }

                    if (File.Exists(destPath))
                    {
                        var srcDi = new FileInfo(srcPath);
                        var destDi = new FileInfo(destPath);

                        if (srcDi.LastWriteTime != destDi.LastWriteTime || srcDi.Length != destDi.Length)
                        {
                            File.Copy(srcPath, destPath, true);
                            UnityEngine.Debug.Log($"CopyLuaBytesFiles: file changed: {srcPath}");
                        }
                        else
                        {
                            //Debug.Log($"CopyLuaBytesFiles2: not change: {files[i]}");
                        }
                    }
                    else
                    {
                        var dirPath = Path.GetDirectoryName(destPath);
                        if (!Directory.Exists(dirPath))
                            Directory.CreateDirectory(dirPath);

                        File.Copy(srcPath, destPath, true);
                    }
                }
            }

            //src中没有的(已删除)
            foreach (var item in destFilesSet)
            {
                UnityEngine.Debug.Log($"CopyLuaBytesFiles: src not exist(delete): {item}");
                File.Delete(item);
            }
        }

        static void EncodeLuaFile(string srcFile, string outFile)
        {
            if (!srcFile.ToLower().EndsWith(".lua"))
            {
                File.Copy(srcFile, outFile, true);
                return;
            }

            var currDir = Directory.GetCurrentDirectory();
            //UnityEngine.Debug.Log(currDir);

            var info = new ProcessStartInfo();
            info.WindowStyle = ProcessWindowStyle.Hidden;
            info.ErrorDialog = true;
            info.Arguments = $"-b -g {Path.GetFullPath(srcFile)} {Path.GetFullPath(outFile)}";

            if (Application.platform == RuntimePlatform.WindowsEditor)
            {
                info.FileName = "luajit.exe";
                info.UseShellExecute = true;

                Directory.SetCurrentDirectory(currDir + "/LuaEncoder/luajit/");
            }
            else if (Application.platform == RuntimePlatform.OSXEditor)
            {
                info.FileName = "./luajit";
                info.UseShellExecute = false;

                Directory.SetCurrentDirectory(currDir + "/LuaEncoder/luajit_mac/");
            }
            UnityEngine.Debug.Log($"{info.FileName} => {info.Arguments}");

            var pro = Process.Start(info);
            pro.WaitForExit();
            Directory.SetCurrentDirectory(currDir);
        }


    } //end of class


}
